﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Win32;
using Autorent.Desktop.Main;
using Autorent.Desktop.Model.AutorentMngrServiceReference;
using Autorent.Desktop.Model.Services;
using Autorent.Desktop.Modules.Employees.Services;
using Autorent.Desktop.Modules.Employees.Views;
using Autorent.Desktop.Modules.Events;
using Autorent.Desktop.Modules.Offices.Services;

namespace Autorent.Desktop.Modules.Employees.ViewModels
{
    public class CreateEmployeeViewModel
    {
        #region Public Properties

        public CreateEmployeeView View { get; set; }

        public Employee Employee { get; set; }

        public ObservableCollection<Office> Offices
        {
            get
            {
                return _officesRepository.GetOffices();
            }
        }

        #endregion

        #region Constructors

        public CreateEmployeeViewModel(CreateEmployeeView view, IEmployeesRepository employeesRepository, IOfficesRepository officesRepository, IEventAggregator eventAggregator,
            IRegionManager regionManager)
        {
            this.View = view;
            View.Model = this;

            _employeesRepository = employeesRepository;
            _officesRepository = officesRepository;
            _regionManager = regionManager;
            _eventAggregator = eventAggregator;

            Employee = new Employee() { EmployeeGender = "m"};
            Employee.SystemUser = new SystemUser();
        }

        #endregion

        #region Commands

        public ICommand SelectPhoto
        {
            get
            {
                return new RelayCommand(param => selectPhoto());
            }
        }

        public ICommand SaveEmployee
        {
            get
            {
                return new RelayCommand(param => saveEmployee());
            }
        }

        public ICommand Cancel
        {
            get
            {
                return new RelayCommand(param => cancel());
            }
        }

        #endregion

        #region Private Variables

        private readonly IEmployeesRepository _employeesRepository;
        private readonly IOfficesRepository _officesRepository;
        private readonly IEventAggregator _eventAggregator;
        private readonly IRegionManager _regionManager;

        #endregion

        #region Private Methods

        private void selectPhoto()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            if (openFileDialog.ShowDialog() == true)
            {
                FileStream fs = new FileStream(openFileDialog.FileName, FileMode.Open);
                byte[] bytes = new byte[fs.Length];
                fs.Read(bytes, 0, (int)fs.Length);

                Employee.EmployeePhoto = ImageResize(fs, 100);
            }
        }

        #region resizing helpers

        //main resizing method (using System.Drawing.Thumbnail class)
        private byte[] ImageResize(FileStream fs, int newWidth)
        {
            //resize image to appropriate size
            System.Drawing.Image.GetThumbnailImageAbort myHandler = new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);

            using (System.Drawing.Image sourceImg = System.Drawing.Image.FromStream(fs))
            {
                double koefOfCompression = (double)(sourceImg.Width / newWidth);
                int newHeight = (int)(sourceImg.Height / koefOfCompression);
                using (System.Drawing.Image thumbnailImage = sourceImg.GetThumbnailImage(newWidth, newHeight, myHandler, IntPtr.Zero))
                {
                    MemoryStream stream = new MemoryStream();
                    try
                    {
                        thumbnailImage.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
                        stream.Position = 0;
                        return stream.ToArray();
                    }
                    catch (Exception ex)
                    {
                        sourceImg.Dispose();
                        stream.Dispose();
                        throw new Autorent.Desktop.Model.AutorentModelException("Error occured while converting image", ex.InnerException);
                    }
                    finally
                    {
                        sourceImg.Dispose();
                        fs.Close();
                        fs.Dispose();
                    }
                }
            }
        }


        // create some ununderstandable shit for thumbnail abort handler
        public bool ThumbnailCallback()
        {
            return false;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        #endregion

        private void saveEmployee()
        {
            _employeesRepository.AddSystemUser(Employee.SystemUser);

            _employeesRepository.AddEmployee(Employee);

            _eventAggregator.GetEvent<CollectionChangedEvent>().Publish("Employees");
            _regionManager.Regions["DetailsRegion"].Remove(View);
        }

        private void cancel()
        {
            _regionManager.Regions["DetailsRegion"].Remove(View);
        }

        #endregion
    }
}
